/*
	Class: StylesManager
	
		Each <Document> has an instance of StylesManager. The StylesManager is
		used as a registry of all the styles available to a document or 
		requested by a document. (That is, a request to an unknown style is
		added to the registry after a warning is issued.)
		
		In a sense though StylesManager is a static class in that the styles
		registry is static and so available to all documents. This is mainly for
		performance reasons and does open the possibility of one document being
		able to affect another one. XXX This should maybe be reconsidered.
		
		The StylesManager is also a registry for the document's stylesheet
		selectors. That is, as stylesheets are parsed, they register their
		<StylesheetSelector> instances with the StylesManager. The reason for
		this is that the registry can collapse equivalent selectors from
		different rulesets to minimize the amount of XML tree searching that
		needs to occur.
*/
package com.frontalcode 
{
	import flash.events.*;
	import fl.transitions.easing.*;
	import flash.utils.*;
	
	/**                  
     * The StylesManager class manages the list of styles for a document.
     */
    public class StylesManager extends OptionableObject
    {
		public var document : Document;
		
		/*
			Variable: allStyles
			
				A registry of all the styles the system knows about.
		*/
		/**            
		 * @private
		 */
		static internal var allStyles : Object;
		
		/*
			Variable: aliasStyles
			
				A registry of all the style aliases the system knows about.
		*/
		/**            
		 * @private
		 */
		static internal var aliasStyles : Object = { };
		
		/*
			Variable: defaultStyles
			 
				Variable that stores styles that have default values.
		*/
		/**            
		 * @private
		 */
		internal var defaultStyles : Styles;
		
		/**            
		 * @private
		 */
		internal var defaultIsDirty : Boolean;
	
		/*
			Variable: moviePropertyStyles
			
				A registry of all the styles that have a direct mapping to a
				display object property.
		*/
		/**            
		 * @private
		 */
		static internal var moviePropertyStyles : Object = [ ];
		
		/*
			Variable: videoPropertyStyles
			
				A registry of all the styles that have a direct mapping to an
				FLVPlayback property.
		*/
		/**            
		 * @private
		 */
		static internal var videoPropertyStyles : Object = [ ];
		
		/*
			Variable: textPropertyStyles
			
				A registry of all the styles that have a direct mapping to an
				TextField property.
		*/
		/**            
		 * @private
		 */
		static internal var textPropertyStyles : Object = [ ];
		
		/*
			Variable: textFormatPropertyStyles
			
				A registry of all the styles that have a direct mapping to an
				TextFormat property.
		*/
		/**            
		 * @private
		 */
		static internal var textFormatPropertyStyles : Object = [ ];
		
		/*
			Variable: stylesheetSelectors
			
				A Dictionary of all our selectors. The keys and the values are
				StylesheetSelectors.
		*/
		/**            
		 * @private
		 */
		internal var stylesheetSelectors : Dictionary = new Dictionary ( );
		
		/*
			Variable: stylesheetSelectorsIdMap
			
				An Object keyed by a stylesheet ruleset's id as specified with
				the Frontal-specific +rulesetId entry in the declarations list.
				For example:
				
					.myClass:hover, div { +rulesetId: myRulesetId }
					
				Note that like in the example, a rulesetId may be associated
				with multiple selectors and so the values in this Object are
				Arrays.
		*/
		/**            
		 * @private
		 */
		internal var stylesheetSelectorsIdMap : Object = { };
		
		/*
			Variable: stylesheetSelectorsNameMap
			
				An Object keyed by our StylesheetSelectors' canonical names. The 
				rules for defining these names are in 
				StylesheetSelector.selectorToString. For example, the selector 
				".myClass:hover" has a canonical name of "*.myClass:hover" where
				the implied universal element is added. Note that a stylesheet
				may have the same selector listed multiple times and so a single
				canonical name may map to multiple StylesheetSelectors.
		*/
		/**            
		 * @private
		 */
		internal var stylesheetSelectorsNameMap : Object = { };
		
		/*
			Variable: defaultStylesheet
			
				The outer <content /> tag is simply to make this proper XML.
				Only the children are added to the document.
		*/
		static public var defaultStylesheet : XML = <content>
			<style><![CDATA[
				document
					{
						width: 100% leftover;
						height: 100% leftover;
					}
				*:link				{ use-hand-cursor: true;  }
				*:visited			{ use-hand-cursor: true;  }
				*:disabled:link		{ use-hand-cursor: false; }
				*:disabled:visited	{ use-hand-cursor: false; }
				.frButtonNext, .frButtonPrev
					{
						is-link: true;
						is-marker: true;
						jump-delta: 1;
 						@onClick { var mgr = gE  ( gA ( "mgrId" ) ); mgr.jumpTo ( mgr.getNext ( gS ( "jump-delta" ), ! gS ( "stop-at-end" ) ) ); }
 						@onSelect 
							{
								if ( event is com.frontalcode.ContainerMgrEvent )
									markedElement = event.manager.getNext ( gS ( "jump-delta" ), ! gS ( "stop-at-end" ), event.next );
								else
									markedElement = gE  ( gA ( "mgrId" ) ).getNext ( gS ( "jump-delta" ), ! gS ( "stop-at-end" ) );
							}
					}
				.frButtonPrev		{ jump-delta: -1; }
				.frMarker
					{
						is-link: true;
						is-marker: true;
						@onClick { gE ( gA ( "mgrId" ) ).jumpTo ( gA ( "elemNdx" ) ); }
					}
				img				
					{ 
						width: auto; 
						height: auto;
						wants-reset: true;
					}
				img:isSymbol:link 		{ go-to-label: link; }
				img:isSymbol:visited 	{ go-to-label: visited; }
				img:isSymbol:selected 	{ go-to-label: selected; }
				img:isSymbol:focus 		{ go-to-label: focus; }
				img:isSymbol:hover 		{ go-to-label: hover; }
				img:isSymbol:active		{ go-to-label: active; }
				img:isSymbol:disabled 	{ go-to-label: disabled; }
				.frLink
					{
						is-link: true;
						@onClick 
							{
								if ( attributeExists ( "fref" ) )
								{
									document.open ( gA ( "fref" ), gA ( "target" ) );
								}
								else if ( attributeExists ( "href" ) )
								{
									flash.net.navigateToURL ( new flash.net.URLRequest ( gA ( "href" ) ), gA ( "target" ) );
								}
							}
					}
				.frScrollbarVert [name=up] 
					{
						is-link: true;
						@onMouseDown { getScrollbarContainer ( ).startPressScrollButton ( false ); }
						@onMouseUp   { getScrollbarContainer ( ).stopPressScrollButton ( ); }
						@onRollOut   { getScrollbarContainer ( ).stopPressScrollButton ( ); }
					}
				.frScrollbarVert [name=down] 
					{
						is-link: true;
						@onMouseDown { getScrollbarContainer ( ).startPressScrollButton ( true ); }
						@onMouseUp   { getScrollbarContainer ( ).stopPressScrollButton ( ); }
						@onRollOut   { getScrollbarContainer ( ).stopPressScrollButton ( ); }
					}
				.frScrollbarVert [name=track]
					{
						height: 100% leftover;
						width: auto;
						overflow: visible;
						layout: stack;
					}
				.frScrollbarVert [name=trackButton]
					{
						is-link: true;
						width: 100% leftover;
						height: 100% leftover;
						overflow: visible;
						background-color: #cccccc;
						border-color: #999999;
						border-width: 1px;
						@onMouseDown { getScrollbarContainer ( ).startPressScrollbarTrack ( event ); }
						@onMouseUp   { getScrollbarContainer ( ).stopPressScrollbarTrack ( ); }
						@onRollOut   { getScrollbarContainer ( ).stopPressScrollbarTrack ( ); }
					}
				.frScrollbarVert [name=slider]
					{
						is-link: true;
						width: 100% leftover;
						height: 20px;
						overflow: visible;
						background-color: #666666;
						border-color: #999999;
						border-width: 1px;
						@onMouseDown		{ getScrollbarContainer ( ).startDragScrollbarSlider ( ); }
						@onMouseUpAnywhere	{ getScrollbarContainer ( ).stopDragScrollbarSlider ( ); }
					}
				.frScrollbarVert
					{
						z-index: 1000000;
						wants-reset: true;
						height: 100%;
						overflow: visible;
						@onReset { parent.scrollTop = 0; }
					}
				.frScrollbarHoriz [name=left] 
					{
						float: left;
						is-link: true;
						@onMouseDown { getScrollbarContainer ( ).startPressScrollButton ( false, false ); }
						@onMouseUp   { getScrollbarContainer ( ).stopPressScrollButton ( false ); }
						@onRollOut   { getScrollbarContainer ( ).stopPressScrollButton ( false ); }
					}
				.frScrollbarHoriz [name=right] 
					{
						float: left;
						is-link: true;
						@onMouseDown { getScrollbarContainer ( ).startPressScrollButton ( true, false ); }
						@onMouseUp   { getScrollbarContainer ( ).stopPressScrollButton ( false ); }
						@onRollOut   { getScrollbarContainer ( ).stopPressScrollButton ( false ); }
					}
				.frScrollbarHoriz [name=track]
					{
						float: left;
						width: 100% leftover;
						height: 100%;
						overflow: visible;
						layout: stack;
					}
				.frScrollbarHoriz [name=trackButton]
					{
						is-link: true;
						width: 100% leftover;
						height: 100% leftover;
						overflow: visible;
						background-color: #cccccc;
						border-color: #999999;
						border-width: 1px;
						@onMouseDown { getScrollbarContainer ( ).startPressScrollbarTrack ( event, false ); }
						@onMouseUp   { getScrollbarContainer ( ).stopPressScrollbarTrack ( false ); }
						@onRollOut   { getScrollbarContainer ( ).stopPressScrollbarTrack ( false ); }
					}
 				.frScrollbarHoriz [name=slider]
					{
						is-link: true;
						height: 100% leftover;
						width: 20px;
						overflow: visible;
						background-color: #666666;
						border-color: #999999;
						border-width: 1px;
						@onMouseDown		{ getScrollbarContainer ( ).startDragScrollbarSlider ( ); }
						@onMouseUpAnywhere	{ getScrollbarContainer ( ).stopDragScrollbarSlider ( ); }
					}
				.frScrollbarHoriz
					{
						z-index: 1000000;
						wants-reset: true;
						width: 100%;
						overflow: visible;
						@onReset { parent.scrollLeft = 0; }
					}
				input[type=hidden]
					{
						display: none;
						@getValue { return gA ( "value" ); }
					}
				input[type=button], input[type=submit]
					{
						@onFirstDocumentPreRender
							{
								input = new fl.controls.Button ( ); 
								movie.addChildAt ( input, 0 );
								if ( gA ( "type" ) == "submit" )
								{
									if ( form != null && gS ( "custom-default-button" ) !== false ) form.defaultButton = this;
									dynamic.clickHandler = function ( ) { dynamic.clicked = true; if ( form != null ) form.submit ( ); dynamic.clicked = false; }
									addListener ( input, flash.events.MouseEvent.CLICK, dynamic.clickHandler );
								}
								needsRender = true;
							}
						@onCustomRender 
							{ 
								if ( ! isNaN ( width ) ) input.width = width;
								if ( ! isNaN ( width ) ) input.height = height;
								input.label = node.text ( ).toString ( );
								input.drawNow ( ); 
							}
						@getValue { if ( dynamic.clicked ) return attributeExists ( "value" ) ? gA ( "value" ) : input.label; return undefined; }
					}
				input[type=checkbox]
					{
						@onFirstDocumentPreRender
							{
								input = new fl.controls.CheckBox ( ); 
								movie.addChildAt ( input, 0 ); 
								needsRender = true;
							}
						@onCustomRender 
							{ 
								var styles = { "custom-label-placement": "labelPlacement", "custom-selected": "selected" };
								for ( var style in styles ) if ( gS ( style ) != null ) input [ styles [ style ] ] = gS ( style );
								if ( ! isNaN ( width ) ) input.width = width;
								if ( ! isNaN ( width ) ) input.height = height;
								input.label = node.text ( ).toString ( );
								input.drawNow ( ); 
							}
						@getValue { return attributeExists ( "value" ) ? ( input.selected ? gA ( "value" ) : undefined ) : input.selected; }
					}
				input[type=radio]
					{
						@onFirstDocumentPreRender
							{
								input = new fl.controls.RadioButton ( );
								if ( form != null && attributeExists ( "name" ) )
								{
									if ( form.dynamic.radioButtonGroups == null ) form.dynamic.radioButtonGroups = { };
									if ( form.dynamic.radioButtonGroups [ gA ( "name" ) ] == null ) form.dynamic.radioButtonGroups [ gA ( "name" ) ] = new fl.controls.RadioButtonGroup ( gA ( "name" ) );
									input.group = form.dynamic.radioButtonGroups [ gA ( "name" ) ]; 
								}
								input.value = gA ( "value" );
								movie.addChildAt ( input, 0 ); 
								needsRender = true;
							}
						@onCustomRender 
							{ 
								var styles = { "custom-label-placement": "labelPlacement", "custom-selected": "selected" };
								for ( var style in styles ) if ( gS ( style ) != null ) input [ styles [ style ] ] = gS ( style );
								if ( ! isNaN ( width ) ) input.width = width;
								if ( ! isNaN ( width ) ) input.height = height;
								input.label = node.text ( ).toString ( );
								input.drawNow ( ); 
							}
						@getValue 
							{
								if ( form != null && attributeExists ( "name" ) )
								{
									return form.dynamic.radioButtonGroups [ gA ( "name" ) ].selectedData;
								}
								else
								{
									return input.value; 
								}
							}
					}
				input[type=file]
					{
						@buttonLabel: Choose Files
						@message: no files selected
						@onFirstDocumentPreRender
							{
								input = new fl.controls.Button ( );
								movie.addChildAt ( input, 0 );
								dynamic.fileReferenceList = new flash.net.FileReferenceList ( );
								dynamic.fileReference = new flash.net.FileReference ( );
								dynamic.fileReferenceBrowsed = false;
								dynamic.clickHandler = function ( event ) 
								{ 
									var filters = [ ];
									for each ( var name in getAttributes ( ) ) 
									{
										if ( name.toLowerCase ( ).indexOf ( "description" ) == 0 )
										{
											var suffix = name.substr ( 11 );
											var extension = attributeExists ( "extension" + suffix ) ? gA ( "extension" + suffix ) : null;
											var macType = attributeExists ( "macType" + suffix ) ? gA ( "macType" + suffix ) : null;
											if ( extension != null ) filters.push ( new flash.net.FileFilter ( gA ( name ), extension, macType ) );
										}
									}
									if ( gS ( "custom-allow-multiple-selection" ) )
									{
										dynamic.fileReferenceList.browse ( filters ); 
									}
									else
									{
										dynamic.fileReference.browse ( filters ); 
										dynamic.fileReferenceBrowsed = true;
									}
								}
								dynamic.onSelectHandler = function ( event ) { dynamic.showFileSelection ( ); }
								dynamic.showFileSelection = function ( )
								{
									var fileSelectionNdx = attributeExists ( "fileSelectionNdx" ) ? gA ( "fileSelectionNdx" ) : ( gA ( "name" ) + "FileSelection" );
									var fileSelection = parentContainer.gE ( fileSelectionNdx, true, false );
									if ( fileSelection != null ) 
									{
										var msg = gA ( "message" );
										if ( gS ( "custom-allow-multiple-selection" ) )
										{
											if ( dynamic.fileReferenceList.fileList != null && dynamic.fileReferenceList.fileList.length > 0 )
											{
												var names = [ ];
												for each ( var file in dynamic.fileReferenceList.fileList ) names.push ( file.name );
												msg = names.join ( ", " );
											}
										}
										else
										{
											if ( dynamic.fileReferenceBrowsed && dynamic.fileReference.name != null ) msg = dynamic.fileReference.name;
										}
										fileSelection.text = msg;
									}
								}
								addListener ( input, flash.events.MouseEvent.CLICK, dynamic.clickHandler );
								addListener ( dynamic.fileReferenceList, flash.events.Event.SELECT, dynamic.onSelectHandler );
								addListener ( dynamic.fileReference, flash.events.Event.SELECT, dynamic.onSelectHandler );
								needsRender = true;
							}
						@onCustomRender 
							{ 
								input.label = gA ( "buttonLabel" );
								if ( ! isNaN ( width ) ) input.width = width;
								if ( ! isNaN ( width ) ) input.height = height;
								input.drawNow ( );
								dynamic.showFileSelection ( );
							}
						@getValue { return gS ( "custom-allow-multiple-selection" ) ? dynamic.fileReferenceList : dynamic.fileReference; }
					}
				input[type=list], input[type=select]
					{
						@onFirstDocumentPreRender
							{
								input = gA ( "type" ) == "list" ? new fl.controls.List ( ) : new fl.controls.ComboBox ( );
								var data = [ ];
								var itemNode = new flash.xml.XMLDocument ( node.toXMLString ( ) ).firstChild.firstChild;
								while ( itemNode != null )
								{ 
									if ( itemNode.nodeName == "item" ) data.push ( { label: itemNode.childNodes, value: itemNode.attributes [ "value" ] != null ? itemNode.attributes [ "value" ] : itemNode.childNodes } );
									itemNode = itemNode.nextSibling;
								}
								input.dataProvider = new fl.data.DataProvider ( data );
								movie.addChildAt ( input, 0 ); 
								needsRender = true;
							}
						@onCustomRender 
							{ 
								var styles = gA ( "type" ) == "list" ? { "custom-allow-multiple-selection": "allowMultipleSelection" } : { };
								for ( var style in styles ) if ( gS ( style ) != null ) input [ styles [ style ] ] = gS ( style );
								if ( ! isNaN ( width ) ) input.width = width;
								if ( ! isNaN ( width ) ) input.height = height;
								input.drawNow ( ); 
							}
						@getValue 
							{
								var value = undefined;
								if ( gA ( "type" ) == "list" )
								{
									for ( var i : int = 0; i < input.selectedItems.length; i++ )
									{
										if ( value == undefined ) value = [ ];
										value.push ( input.selectedItems [ i ].value );
									}
									if ( ! input.allowMultipleSelection && value != undefined && value.length > 0 ) value = value [ 0 ];
								}
								else
								{
									if ( input.selectedItem != null ) value = input.selectedItem.value;
								}
								return value;
							}
					}
				input[type=text], input[type=password], input[type=textarea]
					{
						@onFirstDocumentPreRender
							{
								input = gA ( "type" ) == "textarea" ? new fl.controls.TextArea ( ) : new fl.controls.TextInput ( );
								if ( gA ( "type" ) == "password" ) input.displayAsPassword = true;
								input.text = node.text ( ).toString ( );
								movie.addChildAt ( input, 0 ); 
								needsRender = true;
							}
						@onCustomRender 
							{ 
								if ( ! isNaN ( width ) ) input.width = width;
								if ( ! isNaN ( width ) ) input.height = height;
								input.drawNow ( ); 
							}
						@onFocusInRaw { if ( input != null && input.text == node.text ( ).toString ( ) ) input.text = ""; }
						@onFocusOutRaw { if ( input != null && input.text == "" ) input.text = node.text ( ).toString ( ); }
						@getValue { return input != null && input.text == node.text ( ).toString ( ) ? "" : input.text; }
					}
				input[type=stepper]
					{
						@onFirstDocumentPreRender
							{
								input = new fl.controls.NumericStepper ( ); 
								movie.addChildAt ( input, 0 ); 
								needsRender = true;
							}
						@onCustomRender 
							{ 
								var styles = { "custom-minimum": "minimum", "custom-maximum": "maximum", "custom-step-size": "stepSize" };
								for ( var style in styles ) if ( gS ( style ) != null ) input [ styles [ style ] ] = gS ( style );
								input.value = node.text ( ).toString ( );
								if ( ! isNaN ( width ) ) input.width = width;
								if ( ! isNaN ( width ) ) input.height = height;
								input.drawNow ( ); 
							}
						@getValue { return input.value; }
					}
				input [type=button]
					{
						// XXX Baffling. If the last selector is an element with
						// an attribute selector then we get 10 renders. This is
						// even we don't even parse the thing! Is the E4X parser
						// getting confused? 
					}
				.frProgressIndicator [name=track]
					{
						background-color: #cccccc;
						border-color: #999999;
						border-width: 1px;
						width: 50%;
						height: 5px;
						margin: auto;
					}
				.frProgressIndicator [name=indicator]
					{
						height: 100%;
						width: 0%;
						background-color: #666666;
					}
				.frProgressIndicator
					{
						top: 0px;
						left: 0px;
						display: none;
						@onProgress 
						{
							if ( progress.fraction < 1 ) 
							{
								sS ( "display", "block" );
								gE ( "indicator", false ).sS ( "width", progress.fraction * 100 + "%" );
							}
							else
							{
								sS ( "display", "none" );
							}
						}
					}
			]]></style>
			<template name="frScrollbarVert">
				<div class="frScrollbarVert">
					<!-- <div name="up" /> -->
					<div name="track">
						<div name="trackButton" />
						<div name="slider" />
					</div>
					<!-- <div name="down" /> -->
				</div>
			</template>
			<template name="frScrollbarHoriz">
				<div class="frScrollbarHoriz">
					<!-- <div name="left" /> -->
					<div name="track">
						<div name="trackButton" />
						<div name="slider" />
					</div>
					<!-- <div name="right" /> -->
				</div>
			</template>
			<template name="frProgressIndicator">
				<div class="frProgressIndicator">
					<div name="track">
						<div name="indicator" />
					</div>
				</div>
			</template>
		</content>
		
		/**
		 * Creates a new StylesManager instance.
		 */
		public function StylesManager ( document : Document, options : Object = null )
		{
			super ( options );
			
			this.document = document;
			
			setOptionsFromLoaderParameters ( );
			
			if ( allStyles == null )
			{
				allStyles = { };
				
				var blendMode		: RegExp = /^(add|alpha|darken|difference|erase|hardlight|invert|layer|lighten|multiply|normal|overlay|screen|subtract)$/;
				var textTransform	: RegExp = /^(capitalize|uppercase|lowercase|none)$/;
				var scroll			: RegExp = /^(horizontal|vertical|both|auto|none)$/;
				var shape			: RegExp = /^(rectangle|ellipse|rounded rectangle)$/;
				var resizeScale		: RegExp = /^(showall|showmost|none|stretch)$/;
				var bevelType		: RegExp = /^(inner|outer|full)$/;
				
				registerStyle ( "alpha",								Util.decimal,						1,						{ categories: [ 'movieFormat' ], movieProperty: "alpha" } );
				registerStyle ( "blur",									Util.decimalPx,						undefined,				{ categories: [ 'movieFormat' ], movieProperty: "blur", defaultForTween: 0 } );
				registerStyle ( "blur-x",								Util.decimalPx,						0,						{ categories: [ 'movieFormat' ], movieProperty: "blurX", maskedByStyle: "blur" } );
				registerStyle ( "blur-y",								Util.decimalPx,						0,						{ categories: [ 'movieFormat' ], movieProperty: "blurY", maskedByStyle: "blur" } );
				registerStyle ( "blur-quality",							Util.decimal,						1,						{ categories: [ 'movieFormat' ], movieProperty: "blurQuality" } );
				registerStyle ( "shadow-alpha",							Util.decimal,						1,						{ categories: [ 'movieFormat' ], movieProperty: "shadowAlpha" } );
				registerStyle ( "shadow-angle",							Util.decimal,						45,						{ categories: [ 'movieFormat' ], movieProperty: "shadowAngle" } );
				registerStyle ( "shadow-blur",							Util.decimalPx,						undefined,				{ categories: [ 'movieFormat' ], movieProperty: "shadowBlur", defaultForTween: 4 } );
				registerStyle ( "shadow-blur-x",						Util.decimalPx,						4,						{ categories: [ 'movieFormat' ], movieProperty: "shadowBlurX", maskedByStyle: "shadow-blur" } );
				registerStyle ( "shadow-blur-y",						Util.decimalPx,						4,						{ categories: [ 'movieFormat' ], movieProperty: "shadowBlurY", maskedByStyle: "shadow-blur" } );
				registerStyle ( "shadow-color",							Util.colorVal,						0,						{ categories: [ 'movieFormat' ], movieProperty: "shadowColor", isColor: true, processor: handleColorName } );
				registerStyle ( "shadow-distance",						Util.decimalPx,						0,						{ categories: [ 'movieFormat' ], movieProperty: "shadowDistance" } );
				registerStyle ( "shadow-inner",							Util.booleanVal,					false,					{ categories: [ 'movieFormat' ], movieProperty: "shadowInner" } );
				registerStyle ( "shadow-hide-object",					Util.booleanVal,					false,					{ categories: [ 'movieFormat' ], movieProperty: "shadowHideObject" } );
				registerStyle ( "shadow-knockout",						Util.booleanVal,					false,					{ categories: [ 'movieFormat' ], movieProperty: "shadowKnockout" } );
				registerStyle ( "shadow-quality",						Util.decimal,						1,						{ categories: [ 'movieFormat' ], movieProperty: "shadowQuality" } );
				registerStyle ( "shadow-strength",						Util.decimal,						0,						{ categories: [ 'movieFormat' ], movieProperty: "shadowStrength" } );
				registerStyle ( "glow-alpha",							Util.decimal,						1,						{ categories: [ 'movieFormat' ], movieProperty: "glowAlpha" } );
				registerStyle ( "glow-blur",							Util.decimalPx,						undefined,				{ categories: [ 'movieFormat' ], movieProperty: "glowBlur", defaultForTween: 4 } );
				registerStyle ( "glow-blur-x",							Util.decimalPx,						4,						{ categories: [ 'movieFormat' ], movieProperty: "glowBlurX", maskedByStyle: "glow-blur" } );
				registerStyle ( "glow-blur-y",							Util.decimalPx,						4,						{ categories: [ 'movieFormat' ], movieProperty: "glowBlurY", maskedByStyle: "glow-blur" } );
				registerStyle ( "glow-color",							Util.colorVal,						0,						{ categories: [ 'movieFormat' ], movieProperty: "glowColor", isColor: true, processor: handleColorName } );
				registerStyle ( "glow-inner",							Util.booleanVal,					false,					{ categories: [ 'movieFormat' ], movieProperty: "glowInner" } );
				registerStyle ( "glow-knockout",						Util.booleanVal,					false,					{ categories: [ 'movieFormat' ], movieProperty: "glowKnockout" } );
				registerStyle ( "glow-quality",							Util.decimal,						1,						{ categories: [ 'movieFormat' ], movieProperty: "glowQuality" } );
				registerStyle ( "glow-strength",						Util.decimal,						0,						{ categories: [ 'movieFormat' ], movieProperty: "glowStrength" } );
				registerStyle ( "bevel-distance",						Util.decimalPx,						4,						{ categories: [ 'movieFormat' ], movieProperty: "bevelDistance" } );
				registerStyle ( "bevel-angle",							Util.decimal,						45,						{ categories: [ 'movieFormat' ], movieProperty: "bevelAngle" } );
				registerStyle ( "bevel-highlight-color",				Util.colorVal,						0xffffff,				{ categories: [ 'movieFormat' ], movieProperty: "bevelHighlightColor", isColor: true, processor: handleColorName } );
				registerStyle ( "bevel-highlight-alpha",				Util.decimal,						1,						{ categories: [ 'movieFormat' ], movieProperty: "bevelHighlightAlpha" } );
				registerStyle ( "bevel-shadow-color",					Util.colorVal,						0,						{ categories: [ 'movieFormat' ], movieProperty: "bevelShadowColor", isColor: true, processor: handleColorName } );
				registerStyle ( "bevel-shadow-alpha",					Util.decimal,						1,						{ categories: [ 'movieFormat' ], movieProperty: "bevelShadowAlpha" } );
				registerStyle ( "bevel-blur",							Util.decimalPx,						undefined,				{ categories: [ 'movieFormat' ], movieProperty: "bevelBlur", defaultForTween: 4 } );
				registerStyle ( "bevel-blur-x",							Util.decimalPx,						4,						{ categories: [ 'movieFormat' ], movieProperty: "bevelBlurX", maskedByStyle: "bevel-blur" } );
				registerStyle ( "bevel-blur-y",							Util.decimalPx,						4,						{ categories: [ 'movieFormat' ], movieProperty: "bevelBlurY", maskedByStyle: "bevel-blur" } );
				registerStyle ( "bevel-strength",						Util.decimal,						0,						{ categories: [ 'movieFormat' ], movieProperty: "bevelStrength" } );
				registerStyle ( "bevel-quality",						Util.decimal,						1,						{ categories: [ 'movieFormat' ], movieProperty: "bevelQuality" } );
				registerStyle ( "bevel-type",							bevelType,							"inner",				{ categories: [ 'movieFormat' ], movieProperty: "bevelType" } );
				registerStyle ( "bevel-knockout",						Util.booleanVal,					false,					{ categories: [ 'movieFormat' ], movieProperty: "bevelKnockout" } );
				registerStyle ( "saturation",							Util.decimal,						0,						{ categories: [ 'movieFormat' ], movieProperty: "saturation" } );
				registerStyle ( "contrast",								Util.decimal,						0,						{ categories: [ 'movieFormat' ], movieProperty: "contrast" } );
				registerStyle ( "brightness",							Util.decimal,						0,						{ categories: [ 'movieFormat' ], movieProperty: "brightness" } );
				registerStyle ( "hue",									Util.decimal,						0,						{ categories: [ 'movieFormat' ], movieProperty: "hue" } );
				registerStyle ( "background-alpha",						Util.decimal,						1,						{ categories: [ 'backgroundFormat' ], aliases: [ "background-opacity" ] } );
				registerStyle ( "margin-top",							Util.lengthSpec,					0,						{ categories: [ 'layout' ], containerProperty: "marginTop", dimensionStyle: "height" } );
				registerStyle ( "margin-left",							Util.lengthSpec,					0,						{ categories: [ 'layout' ], containerProperty: "marginLeft", dimensionStyle: "width" } );
				registerStyle ( "margin-right",							Util.lengthSpec,					0,						{ categories: [ 'layout' ], containerProperty: "marginRight", dimensionStyle: "width" } );
				registerStyle ( "margin-bottom",						Util.lengthSpec,					0,						{ categories: [ 'layout' ], containerProperty: "marginBottom", dimensionStyle: "height" } );
				registerStyle ( "margin",								Util.upToFourLengthSpec,			undefined,				{ processor: handleFourValues } );
				registerStyle ( "padding-top",							Util.lengthSpec,					0,						{ categories: [ 'layout' ], containerProperty: "paddingTop", dimensionStyle: "height" } );
				registerStyle ( "padding-left",							Util.lengthSpec,					0,						{ categories: [ 'layout' ], containerProperty: "paddingLeft", dimensionStyle: "width" } );
				registerStyle ( "padding-right",						Util.lengthSpec,					0,						{ categories: [ 'layout' ], containerProperty: "paddingRight", dimensionStyle: "width" } );
				registerStyle ( "padding-bottom",						Util.lengthSpec,					0,						{ categories: [ 'layout' ], containerProperty: "paddingBottom", dimensionStyle: "height" } );
				registerStyle ( "padding",								Util.upToFourLengthSpec,			undefined,				{ processor: handleFourValues } );
				registerStyle ( "border-top-width",						Util.lengthSpec,					0,						{ categories: [ 'layout' ], containerProperty: "borderTop", dimensionStyle: "height" } );
				registerStyle ( "border-left-width",					Util.lengthSpec,					0,						{ categories: [ 'layout' ], containerProperty: "borderLeft", dimensionStyle: "width" } );
				registerStyle ( "border-right-width",					Util.lengthSpec,					0,						{ categories: [ 'layout' ], containerProperty: "borderRight", dimensionStyle: "width" } );
				registerStyle ( "border-bottom-width",					Util.lengthSpec,					0,						{ categories: [ 'layout' ], containerProperty: "borderBottom", dimensionStyle: "height" } );
				registerStyle ( "border-width",							Util.upToFourLengthSpec,			undefined,				{ processor: handleFourValues } );
				registerStyle ( "border-color",							Util.colorVal,						0,						{ categories: [ 'backgroundFormat' ], cascading: true, isColor: true, processor: handleColorName } );
				registerStyle ( "border-alpha",							Util.decimal,						1,						{ categories: [ 'backgroundFormat' ], aliases: [ "border-opacity" ], cascading: true } );
				registerStyle ( "z-index",								styleIsNumber,						0,						{ doNotTween: true } );
				registerStyle ( "scale",								Util.decimal,						undefined,				{ categories: [ 'layout', 'movieFormat' ], movieProperty: "scale", defaultForTween: 1 } );
				registerStyle ( "scale-x",								Util.decimal,						1,						{ categories: [ 'layout', 'movieFormat' ], movieProperty: "scaleX", maskedByStyle: "scale" } );
				registerStyle ( "scale-y",								Util.decimal,						1,						{ categories: [ 'layout', 'movieFormat' ], movieProperty: "scaleY", maskedByStyle: "scale" } );
				registerStyle ( "scale-z",								Util.decimal,						undefined,				{ categories: [ 'movieFormat' ], movieProperty: "scaleZ" } );
				registerStyle ( "rotation",								Util.decimal,						0,						{ categories: [ 'movieFormat' ], movieProperty: "rotation" } );
				registerStyle ( "rotation-x",							Util.decimal,						undefined,				{ categories: [ 'movieFormat' ], movieProperty: "rotationX" } );
				registerStyle ( "rotation-y",							Util.decimal,						undefined,				{ categories: [ 'movieFormat' ], movieProperty: "rotationY" } );
				registerStyle ( "rotation-z",							Util.decimal,						undefined,				{ categories: [ 'movieFormat' ], movieProperty: "rotationZ" } );
				registerStyle ( "display",								/^(block|none)$/,					"block",				{ categories: [ 'layout' ] } );
				registerStyle ( "width",								Util.lengthSpec,					undefined,				{ categories: [ 'layout' ], containerProperty: "width", dimensionStyle: "width" } );
				registerStyle ( "height",								Util.lengthSpec,					undefined,				{ categories: [ 'layout' ], containerProperty: "height", dimensionStyle: "height" } );
				registerStyle ( "left",									Util.lengthSpec,					undefined,				{ categories: [ 'layout' ], containerProperty: "left", dimensionStyle: "width" } );
				registerStyle ( "top",									Util.lengthSpec,					undefined,				{ categories: [ 'layout' ], containerProperty: "top", dimensionStyle: "height" } );
				registerStyle ( "bottom",								Util.lengthSpec,					undefined,				{ categories: [ 'layout' ], containerProperty: "bottom", dimensionStyle: "height" } );
				registerStyle ( "right",								Util.lengthSpec,					undefined,				{ categories: [ 'layout' ], containerProperty: "right", dimensionStyle: "width" } );
				registerStyle ( "depth",								Util.decimalPxOrPercent,			undefined,				{ categories: [ 'movieFormat' ] } );
				registerStyle ( "use-hand-cursor",						Util.booleanVal,					undefined,				{ categories: [ 'movieFormat' ], movieProperty: "useHandCursor" } );
				registerStyle ( "button-mode",							Util.booleanVal,					undefined,				{ categories: [ 'movieFormat', 'buttonFormat' ], movieProperty: "buttonMode" } );
				registerStyle ( "mouse-children",						Util.booleanVal,					undefined,				{ categories: [ 'movieFormat', 'buttonFormat' ], movieProperty: "mouseChildren" } );
				registerStyle ( "tab-children",							Util.booleanVal,					undefined,				{ categories: [ 'movieFormat', 'buttonFormat' ], movieProperty: "tabChildren" } );
				registerStyle ( "tab-enabled",							Util.booleanVal,					undefined,				{ categories: [ 'movieFormat' ], movieProperty: "tabEnabled" } );
				registerStyle ( "double-click-enabled",					Util.booleanVal,					undefined,				{ categories: [ 'movieFormat' ], movieProperty: "doubleClickEnabled" } );
				registerStyle ( "mouse-enabled",						Util.booleanVal,					undefined,				{ categories: [ 'movieFormat' ], movieProperty: "mouseEnabled" } );
				registerStyle ( "movie-registration-x",					Util.decimalPxOrPercent,			0,						{ categories: [ 'movieFormat' ] } );
				registerStyle ( "movie-registration-y",					Util.decimalPxOrPercent,			0,						{ categories: [ 'movieFormat' ] } );
				registerStyle ( "cache-as-bitmap",						Util.booleanVal,					undefined,				{ categories: [ 'movieFormat' ], movieProperty: "cacheAsBitmap" } );
				registerStyle ( "background-color",						Util.colorVal,						undefined,				{ categories: [ 'backgroundFormat' ], isColor: true, processor: handleColorName } );
				registerStyle ( "background-image",						null,								undefined,				{ categories: [ 'backgroundFormat' ] } );
				registerStyle ( "background-shape",						shape,								"rectangle",			{ categories: [ 'backgroundFormat' ] } );
				registerStyle ( "bg-shape-ellipse-width",				Util.lengthSpec,					0,						{ categories: [ 'backgroundFormat' ], cascading: true, dimensionStyle: "width" } );
				registerStyle ( "bg-shape-ellipse-height",				Util.lengthSpec,					0,						{ categories: [ 'backgroundFormat' ], cascading: true, dimensionStyle: "height" } );
				registerStyle ( "bg-gradient-type",						/^(linear|radial|none)$/,			undefined,				{ categories: [ 'backgroundFormat' ] } );
				registerStyle ( "bg-gradient-colors",					null,								undefined,				{ categories: [ 'backgroundFormat' ], processor: interpretActionScript, cascading: true } );
				registerStyle ( "bg-gradient-alphas",					null,								undefined,				{ categories: [ 'backgroundFormat' ], processor: interpretActionScript, cascading: true } );
				registerStyle ( "bg-gradient-ratios",					null,								undefined,				{ categories: [ 'backgroundFormat' ], processor: interpretActionScript, cascading: true } );
				registerStyle ( "bg-gradient-matrix",					null,								undefined,				{ categories: [ 'backgroundFormat' ], processor: interpretActionScript, cascading: true } );
				registerStyle ( "bg-gradient-spread",					/^(pad|reflect|repeat)$/,			undefined,				{ categories: [ 'backgroundFormat' ], cascading: true } );
				registerStyle ( "bg-gradient-interpolation",			/^(linearRGB|rgb)$/,				undefined,				{ categories: [ 'backgroundFormat' ], cascading: true } );
				registerStyle ( "bg-gradient-focal-point-ratio",		Util.decimal,						undefined,				{ categories: [ 'backgroundFormat' ], cascading: true } );
				registerStyle ( "border-shape",							shape,								undefined,				null );
				registerStyle ( "border-shape-ellipse-width",			Util.lengthSpec,					0,						{ categories: [ 'backgroundFormat' ], cascading: true, dimensionStyle: "width" } );
				registerStyle ( "border-shape-ellipse-height",			Util.lengthSpec,					0,						{ categories: [ 'backgroundFormat' ], cascading: true, dimensionStyle: "height" } );
				registerStyle ( "border-gradient-type",					/^(linear|radial|none)$/,			undefined,				null );
				registerStyle ( "border-gradient-colors",				null,								undefined,				{ categories: [ 'backgroundFormat' ], processor: interpretActionScript, cascading: true } );
				registerStyle ( "border-gradient-alphas",				null,								undefined,				{ categories: [ 'backgroundFormat' ], processor: interpretActionScript, cascading: true } );
				registerStyle ( "border-gradient-ratios",				null,								undefined,				{ categories: [ 'backgroundFormat' ], processor: interpretActionScript, cascading: true } );
				registerStyle ( "border-gradient-matrix",				null,								undefined,				{ categories: [ 'backgroundFormat' ], processor: interpretActionScript, cascading: true } );
				registerStyle ( "border-gradient-spread",				/^(pad|reflect|repeat)$/,			undefined,				{ categories: [ 'backgroundFormat' ], cascading: true } );
				registerStyle ( "border-gradient-interpolation",		/^(linearRGB|rgb)$/,				undefined,				{ categories: [ 'backgroundFormat' ], cascading: true } );
				registerStyle ( "border-gradient-focal-point-ratio",	Util.decimal,						undefined,				{ categories: [ 'backgroundFormat' ], cascading: true } );
				registerStyle ( "blend-mode",							blendMode,							undefined,				{ categories: [ 'movieFormat' ], movieProperty: "blendMode" } );
				registerStyle ( "visibility",							/^(visible|hidden)$/,				undefined,				null );
				registerStyle ( "float",								/^(left|right|none)$/,				"none",					{ categories: [ 'layout' ] } );
				registerStyle ( "disabled",								Util.booleanVal,					false,					null );
				registerStyle ( "mask",									null,								undefined,				{ categories: [ 'maskFormat' ] } );
				registerStyle ( "scale-mask",							Util.booleanVal,					false,					{ categories: [ 'maskFormat' ] } );
				registerStyle ( "clear",								/^(left|right|both|none)$/,			"none",					{ categories: [ 'layout' ] } );
				// XXX Is this working? Undocumented for now.
				registerStyle ( "preload-assets",						Util.booleanVal,					true,					null );
				registerStyle ( "allow-smoothing",						Util.booleanVal,					false,					{ categories: [ 'imgFormat' ], cascading: true } );
				registerStyle ( "auto-play",							Util.booleanVal,					false,					null );
				registerStyle ( "stop-at-end",							Util.booleanVal,					false,					null );
				registerStyle ( "pause-at-transition-end",				Util.booleanVal,					false,					{ cascading: true } );
				registerStyle ( "initial-jump-is-quick",				Util.booleanVal,					true,					null );
				registerStyle ( "hide-unselected",						Util.booleanVal,					false,					{ categories: [ 'layout' ], cascading: true } );
				registerStyle ( "tween-container-init",					Util.booleanVal,					false,					{ cascading: true } );
				registerStyle ( "tween-container-reset",				Util.booleanVal,					false,					{ cascading: true } );
				registerStyle ( "tween-container-ease",					null,								Regular.easeOut,		{ processor: handleFunctionRef, cascading: true } );
				registerStyle ( "resize-anchors",						styleIsAnchors,						undefined,				{ categories: [ 'layout' ], processor: handleResizeAnchors } );
				registerStyle ( "resize-scale-origin",					styleIsScaleOrigin,					undefined,				{ categories: [ 'resize' ] } );
				registerStyle ( "resize-scale",							resizeScale,						"none",					{ categories: [ 'resize' ] } );
				registerStyle ( "pin-to-container",						null,								undefined,				{ categories: [ 'layout' ] } );
				registerStyle ( "pin-to-stage",							Util.booleanVal,					undefined,				{ categories: [ 'layout' ] } );
				registerStyle ( "pin-movie",							Util.booleanVal,					undefined,				{ categories: [ 'layout' ] } );
				registerStyle ( "video-enable-with-show",				Util.booleanVal,					true,					{ categories: [ 'videoFormat' ], cascading: true } );
				registerStyle ( "video-auto-play",						Util.booleanVal,					false,					{ categories: [ 'videoFormat' ], videoProperty: "autoPlay", cascading: true } );
				registerStyle ( "video-auto-rewind",					Util.booleanVal,					true,					{ categories: [ 'videoFormat' ], videoProperty: "autoRewind", cascading: true } );
				registerStyle ( "video-loop",							Util.booleanVal,					false,					{ categories: [ 'videoFormat' ], cascading: true } );
				registerStyle ( "video-skin",							null,								undefined,				{ categories: [ 'videoFormat' ], videoProperty: "skin", cascading: true } );
				registerStyle ( "video-skin-auto-hide",					Util.booleanVal,					false,					{ categories: [ 'videoFormat' ], videoProperty: "skinAutoHide", cascading: true } );
				registerStyle ( "video-skin-background-alpha",			Util.decimal,						undefined,				{ categories: [ 'videoFormat' ], videoProperty: "skinBackgroundAlpha", aliases: [ "video-skin-background-opacity" ], cascading: true } );
				registerStyle ( "video-skin-background-color",			Util.colorVal,						undefined,				{ categories: [ 'videoFormat' ], videoProperty: "skinBackgroundColor", isColor: true, processor: handleColorName, cascading: true } );
				registerStyle ( "video-skin-fade-time",					Util.decimal,						undefined,				{ categories: [ 'videoFormat' ], videoProperty: "skinFadeTime", cascading: true } );
				registerStyle ( "video-skin-scale-maximum",				Util.decimal,						undefined,				{ categories: [ 'videoFormat' ], videoProperty: "skinScaleMaximum", cascading: true } );
				registerStyle ( "video-volume",							Util.decimal,						undefined,				{ categories: [ 'videoFormat' ], videoProperty: "volume", cascading: true } );
				registerStyle ( "video-buffer-time",					Util.decimal,						undefined,				{ categories: [ 'videoFormat' ], videoProperty: "bufferTime", cascading: true } );
				registerStyle ( "video-full-screen-background-color",	Util.colorVal,						undefined,				{ categories: [ 'videoFormat' ], videoProperty: "fullScreenBackgroundColor", isColor: true, processor: handleColorName, cascading: true } );
				registerStyle ( "video-full-screen-skin-delay",			Util.decimal,						undefined,				{ categories: [ 'videoFormat' ], videoProperty: "fullScreenSkinDelay", cascading: true } );
				registerStyle ( "video-full-screen-take-over",			Util.booleanVal,					true,					{ categories: [ 'videoFormat' ], videoProperty: "fullScreenTakeOver", cascading: true } );
				registerStyle ( "base-url",								null,								undefined,				{ cascading: true } );
				registerStyle ( "reset-on-select",						Util.booleanVal,					true,					{ cascading: true } );
				registerStyle ( "reset-on-deselect",					Util.booleanVal,					undefined,				{ cascading: true } );
				registerStyle ( "reset-on-select-transition-end",		Util.booleanVal,					undefined,				{ cascading: true } );
				registerStyle ( "reset-on-deselect-transition-end",		Util.booleanVal,					undefined,				{ cascading: true } );
				registerStyle ( "reset-on-will-select",					Util.booleanVal,					undefined,				{ cascading: true } );
				registerStyle ( "reset-go-to-label",					null,								undefined,				{ cascading: true } );
				registerStyle ( "reset-go-to-and-play",					Util.booleanVal,					undefined,				{ cascading: true } );
				registerStyle ( "font-family",							null,								null,					{ categories: [ 'textFormat' ], cascading: true } );
				registerStyle ( "layout",								/^(stack|normal)$/,					undefined,				{ categories: [ 'layout' ] } );
				registerStyle ( "flash-text-always-show-selection",		Util.booleanVal,					false,					{ categories: [ 'textFormat' ], textProperty: "alwaysShowSelection", cascading: true } );
				registerStyle ( "flash-text-anti-alias-type",			/^(normal|advanced)$/,				"normal",				{ categories: [ 'textFormat' ], textProperty: "antiAliasType", cascading: true } );
				registerStyle ( "condense-white",						Util.booleanVal,					false,					{ categories: [ 'textLayout', 'textFormat' ], textProperty: "condenseWhite", cascading: true } );
				registerStyle ( "display-as-password",					Util.booleanVal,					false,					{ categories: [ 'textLayout', 'textFormat' ], textProperty: "displayAsPassword", cascading: true } );
				registerStyle ( "flash-text-grid-fit-type",				/^(none|pixel|subpixel)$/,			"pixel",				{ categories: [ 'textLayout', 'textFormat' ], textProperty: "gridFitType", cascading: true } );
				registerStyle ( "max-chars",							Util.posInteger,					0,						{ categories: [ 'textFormat' ], textProperty: "maxChars", cascading: true } );
				registerStyle ( "html-text",							Util.booleanVal,					true,					{ categories: [ 'textLayout' ], cascading: true } );
				registerStyle ( "mouse-wheel-enabled",					Util.booleanVal,					true,					{ categories: [ 'textFormat' ], textProperty: "mouseWheelEnabled", cascading: true } );
				registerStyle ( "multiline",							Util.booleanVal,					true,					{ categories: [ 'textLayout', 'textFormat' ], textProperty: "multiline", cascading: true } );
				registerStyle ( "flash-text-restrict",					null,								undefined,				{ categories: [ 'textLayout', 'textFormat' ], textProperty: "restrict", cascading: true } );
				registerStyle ( "selectable",							Util.booleanVal,					true,					{ categories: [ 'textFormat' ], textProperty: "selectable", cascading: true } );
				registerStyle ( "sharpness",							Util.integer,						0,						{ categories: [ 'textFormat' ], textProperty: "sharpness", cascading: true } );
				registerStyle ( "thickness",							Util.integer,						0,						{ categories: [ 'textLayout', 'textFormat' ], textProperty: "thickness", cascading: true } );
				registerStyle ( "flash-text-type",						/^(dynamic|input)$/,				"dynamic",				{ categories: [ 'textFormat' ], textProperty: "type", cascading: true } );
				registerStyle ( "flash-text-use-rich-text-clipboard",	Util.booleanVal,					false,					{ categories: [ 'textFormat' ], textProperty: "useRichTextClipboard", cascading: true } );
				registerStyle ( "word-wrap",							Util.booleanVal,					true,					{ categories: [ 'textLayout', 'textFormat' ], textProperty: "wordWrap", cascading: true } );
				registerStyle ( "text-align",							/^(center|justify|left|right)$/,	"left",					{ categories: [ 'textLayout', 'textFormat' ], textFormatProperty: "align", cascading: true } );
				registerStyle ( "color",								Util.colorVal,						0,						{ categories: [ 'textFormat' ], textProperty: "textColor", isColor: true, processor: handleColorName, cascading: true } );
				registerStyle ( "bold",									Util.booleanVal,					false,					{ categories: [ 'textLayout', 'textFormat' ], textFormatProperty: "bold", cascading: true } );
				registerStyle ( "flash-text-bullet",					Util.booleanVal,					false,					{ categories: [ 'textLayout', 'textFormat' ], textFormatProperty: "bullet", cascading: true } );
				registerStyle ( "indent",								Util.decimalPx,						null,					{ categories: [ 'textLayout', 'textFormat' ], textFormatProperty: "indent", cascading: true } );
				registerStyle ( "italic",								Util.booleanVal,					false,					{ categories: [ 'textLayout', 'textFormat' ], textFormatProperty: "italic", cascading: true } );
				registerStyle ( "kerning",								Util.booleanVal,					false,					{ categories: [ 'textLayout', 'textFormat' ], textFormatProperty: "kerning", cascading: true } );
				registerStyle ( "leading",								Util.decimalPx,						null,					{ categories: [ 'textLayout', 'textFormat' ], textFormatProperty: "leading", cascading: true } );
				registerStyle ( "flash-text-left-margin",				Util.decimalPx,						null,					{ categories: [ 'textLayout', 'textFormat' ], textFormatProperty: "leftMargin", cascading: true } );
				registerStyle ( "letter-spacing",						Util.decimalPx,						null,					{ categories: [ 'textLayout', 'textFormat' ], textFormatProperty: "letterSpacing", cascading: true } );
				registerStyle ( "flash-text-right-margin",				Util.decimalPx,						null,					{ categories: [ 'textLayout', 'textFormat' ], textFormatProperty: "rightMargin", cascading: true } );
				registerStyle ( "block-indent",							Util.decimalPx,						null,					{ categories: [ 'textLayout', 'textFormat' ], textFormatProperty: "blockIndent", cascading: true } );
				registerStyle ( "font-size",							Util.decimalPxOrPercent,			null,					{ categories: [ 'textLayout', 'textFormat' ], textFormatProperty: "size", cascading: true } );
				// XXX flash-text-tab-stops has problems so is undocumented.
				registerStyle ( "flash-text-tab-stops",					null,								null,					{ categories: [ 'textLayout', 'textFormat' ], textFormatProperty: "tabStops", cascading: true } );
				// XXX flash-text-url has problems so flash-text-target is undocumented.
				registerStyle ( "flash-text-target",					null,								null,					{ categories: [ 'textFormat' ], textFormatProperty: "target", cascading: true } );
				registerStyle ( "underline",							Util.booleanVal,					false,					{ categories: [ 'textFormat' ], textFormatProperty: "underline", cascading: true } );
				// XXX flash-text-url has problems so is undocumented.
				registerStyle ( "flash-text-url",						null,								null,					{ categories: [ 'textFormat' ], textFormatProperty: "url" } );
				registerStyle ( "link-color",							Util.colorVal,						undefined,				{ categories: [ 'textFormat' ], cascading: true, isColor: true, processor: handleColorName } );
				registerStyle ( "link-decoration",						/^(none|underline)$/,				undefined,				{ categories: [ 'textFormat' ], cascading: true } );
				registerStyle ( "hover-color",							Util.colorVal,						undefined,				{ categories: [ 'textFormat' ], cascading: true, isColor: true, processor: handleColorName } );
				registerStyle ( "hover-decoration",						/^(none|underline)$/,				undefined,				{ categories: [ 'textFormat' ], cascading: true } );
				registerStyle ( "text-transform",						textTransform,						"none",					{ categories: [ 'textLayout' ], cascading: true } );
				registerStyle ( "style-tween-duration",					Util.decimal,						undefined,				{ doNotTween: true, cascading: true } );
				registerStyle ( "style-remove-tween-duration",			Util.decimal,						undefined,				{ doNotTween: true, cascading: true } );
				registerStyle ( "style-tween-use-secs",					Util.booleanVal,					false,					{ cascading: true } );
				registerStyle ( "style-tween-ease",						null,								Regular.easeOut,		{ processor: handleFunctionRef, cascading: true } );
				registerStyle ( "hold-time",							Util.decimal,						0,						{ cascading: true } );
				registerStyle ( "hold-time-use-secs",					Util.booleanVal,					false,					{ cascading: true } );
				registerStyle ( "is-link",								Util.booleanVal,					false,					null );
				registerStyle ( "is-marker",							Util.booleanVal,					false,					null );
				registerStyle ( "jump-delta",							Util.integer,						1,						null );
				registerStyle ( "overflow",								/^(hidden|visible)$/,				"visible",				{ categories: [ 'maskFormat' ] } );
				registerStyle ( "scrollbar-height",						Util.decimalPx,						10,						{ categories: [ 'scrollbarFormat' ], cascading: true } );
				registerStyle ( "scrollbar-width",						Util.decimalPx,						10,						{ categories: [ 'scrollbarFormat' ], cascading: true } );
				registerStyle ( "scroll",								scroll,								"none",					null );
				registerStyle ( "scrollbar-horizontal-template",		null,								"frScrollbarHoriz",		{ categories: [ 'scrollbarFormat' ], cascading: true } );
				registerStyle ( "scrollbar-vertical-template",			null,								"frScrollbarVert",		{ categories: [ 'scrollbarFormat' ], cascading: true } );
				registerStyle ( "scrollbar-placement",					styleIsAnchors,						"right bottom",			{ categories: [ 'layout' ], cascading: true } );
				// XXX This is not yet implemented to undocumented.
				registerStyle ( "scrollbar-container-id",				null,								undefined,				null );
				registerStyle ( "scrollbar-scale-slider",				Util.booleanVal,					true,					{ categories: [ 'scrollbarFormat' ], cascading: true } );
				registerStyle ( "scroll-disable-buttons",				Util.booleanVal,					true,					{ cascading: true } );
				registerStyle ( "scroll-wheel-smooth",					Util.booleanVal,					false,					{ cascading: true } );
				registerStyle ( "scroll-wheel-sensitivity",				Util.decimal,						1,						{ cascading: true } );
				registerStyle ( "scroll-by-button-click",				Util.lengthSpec,					12,						{ cascading: true } );
				registerStyle ( "scroll-by-button-press",				Util.lengthSpec,					12,						{ cascading: true } );
				registerStyle ( "scroll-text-by-button-click",			Util.integer,						1,						{ cascading: true } );
				registerStyle ( "scroll-text-by-button-press",			Util.integer,						1,						{ cascading: true } );
				registerStyle ( "scroll-by-track-click",				Util.lengthSpec,					"100%",					{ cascading: true } );
				registerStyle ( "scroll-by-track-press",				Util.lengthSpec,					"25%",					{ cascading: true } );
				registerStyle ( "scroll-tween-duration",				Util.decimal,						5,						{ doNotTween: true, cascading: true } );
				registerStyle ( "scroll-scale-tween-duration",			Util.booleanVal,					false,					{ cascading: true } );
				registerStyle ( "scroll-tween-use-secs",				Util.booleanVal,					false,					{ cascading: true } );
				registerStyle ( "scroll-tween-ease",					null,								Regular.easeOut,		{ processor: handleFunctionRef, cascading: true } );
				registerStyle ( "scrollable",							Util.booleanVal,					undefined,				null );
				registerStyle ( "click-max-frames",						Util.posInteger,					6,						{ cascading: true } );
				registerStyle ( "go-to-label",							null,								undefined,				null );
				registerStyle ( "go-to-and-play",						Util.booleanVal,					false,					{ cascading: true } );
				registerStyle ( "control-attacher-index",				null,								undefined,				null );
				registerStyle ( "deep-link",							/^(none|path|query)$/,				"none",					null );
				registerStyle ( "deep-link-delay",						Util.decimal,						undefined,				{ cascading: true } );
				registerStyle ( "deep-link-delay-use-secs",				Util.booleanVal,					false,					{ cascading: true } );
				registerStyle ( "wants-reset",							Util.booleanVal,					undefined,				null );
				registerStyle ( "reset-dispatcher",						null,								undefined,				null );
				registerStyle ( "processes-own-content",				Util.booleanVal,					undefined,				null );
				registerStyle ( "form-auto-focus",						Util.booleanVal,					true,					{ cascading: true } );
				registerStyle ( "progress-includes-all-assets",			Util.booleanVal,					false,					{ cascading: true } );
				registerStyle ( "progress-weight",						Util.decimal,						1,						null );
				registerStyle ( "show-progress-indicator",				/^(never|always|normal)$/,			"never",				null );
				registerStyle ( "progress-indicator-template",			null,								"frProgressIndicator",	{ cascading: true } );
				registerStyle ( "check-policy-file",					Util.booleanVal,					undefined,				null );
				registerStyle ( "policy-file-url",						null,								undefined,				null );
				registerStyle ( "load-in-current-app-and-sec-domains",	Util.booleanVal,					undefined,				null );
				registerStyle ( "include-frontal-form-variables",		Util.booleanVal,					undefined,				{ cascading: true } );
				registerStyle ( "resend-vars-in-multi-file-uploads",	Util.booleanVal,					undefined,				{ cascading: true } );
				registerStyle ( "disable-rendering",					Util.booleanVal,					undefined,				null );
				registerStyle ( "disable-display-list-mgmt",			Util.booleanVal,					undefined,				null );
			}
			
			generateDefaultStyles ( );
		}
		
		/**            
		 * @private
		 */
		static public function styleIsNumber ( styleDefn : Object, value : * ) : Boolean { return ! isNaN ( value ); }
		
		/**            
		 * @private
		 */
		static public function styleIsAnchors ( styleDefn : Object, value : * ) : Boolean 
		{ 
			var values : Array = ( value as String ).split ( /\s+/ );
			
			var test : RegExp = /^(top|right|bottom|left)$/;
			
			for each ( var i : String in values )
			{
				if ( ! test.test ( i ) ) return false;
			}

			return true; 
		}
		
		/**            
		 * @private
		 */
		static public function styleIsScaleOrigin ( styleDefn : Object, value : * ) : Boolean 
		{ 
			var values : Array = ( value as String ).split ( /\s+/ );
			
			var test1 : RegExp = /^(top|bottom|middle)$/;
			var test2 : RegExp = /^(left|right|center)$/;
			
			if ( values.length > 2 ) return false;
			if ( values.length == 1 ) return test1.test ( values [ 0 ] ) || test2.test ( values [ 0 ] );
			if ( values.length == 2 ) 
			{
				if ( test1.test ( values [ 0 ] ) ) return test2.test ( values [ 1 ] );
				if ( test2.test ( values [ 0 ] ) ) return test1.test ( values [ 1 ] );
			}
			
			return false; 
		}
			
		/*
			Function: registerStyle
			
				Register all the styles we know about. (Custom classes may also 
				call this to register their own styles.
				
				The style options are:
				
				uninheritable
				cascading
				aliases			(a list of equivalent style names)
				movieProperty	(a DisplayObject property that maps to this style)
				videoProperty 	(an FLVPlayback property that maps to this style)
				processor		(a function to process complex values or compound style, e.g., margin)
		*/
 		public function registerStyle ( style : String, validator : *, defaultValue : *, options : Object ) : Object
		{
			var styleDefn : Object = allStyles [ style ];
			if ( styleDefn == null ) styleDefn = { };
			styleDefn.style = style;
			styleDefn.validator = validator;
			styleDefn.defaultValue = defaultValue;
			styleDefn.options = options == null ? { } : options;
			allStyles [ style ] = styleDefn;
			if ( styleDefn.options.movieProperty      ) moviePropertyStyles.push ( style );
			if ( styleDefn.options.videoProperty      ) videoPropertyStyles.push ( style );
			if ( styleDefn.options.textProperty       ) textPropertyStyles.push ( style );
			if ( styleDefn.options.textFormatProperty ) textFormatPropertyStyles.push ( style );
			defaultIsDirty = true;
			
			if ( styleDefn.options.aliases != null )
			{
				for each ( var alias : String in styleDefn.options.aliases )
				{
					aliasStyles [ alias ] = style;
				}
			}
			
			return styleDefn;
		}
		
		public function getStyleDefn ( style : String ) : Object
		{
			var styleDefn : Object = allStyles [ aliasStyles [ style.toLowerCase ( ) ] != null ? aliasStyles [ style.toLowerCase ( ) ] : style.toLowerCase ( ) ];
			
			if ( styleDefn == null )
			{
				if ( style.indexOf ( "custom-" ) != 0 ) Debugger.logMessage ( Debugger.INFO, "Styles", "unknown style " + style );
				
				styleDefn = registerStyle ( style, null, null, { unknown: true } );
			}
			
			return styleDefn;
		}
		
		/**            
		 * @private
		 */
		internal function generateDefaultStyles ( ) : void
		{
			if ( defaultStyles == null ) 
			{ 
				defaultStyles = new Styles ( this ); 
				defaultIsDirty = true;
			}
			
			if ( defaultIsDirty )
			{
				// XXX Check to see if an actual change has occurred.
				//
				
				defaultStyles.untouchStyles ( );
				
				for each ( var styleDefn : Object in allStyles )
				{
					if ( styleDefn.defaultValue !== undefined ) defaultStyles.setStyle ( styleDefn.style, styleDefn.defaultValue );
				}
				
				defaultStyles.deleteUntouchedStyles ( );
				defaultStyles.dispatchEvent ( new FrontalEvent ( FrontalEvent.CHANGE ) );
				defaultIsDirty = false;
			}
		}
		
		/**            
		 * @private
		 */
		internal function interpretActionScript ( styleDefn : Object, value : *, rawValue : Boolean = false ) : Array
		{
			return [ { styleDefn: styleDefn, value: rawValue ? ActionScriptInterpreter.evaluate ( value, null, null, { }, null, document ) : value } ];
		}
		
		/**            
		 * @private
		 */
		internal function handleResizeAnchors ( styleDefn : Object, value : *, rawValue : Boolean = false ) : Array
		{
			var styles : Array = [ ];
			
			// Handle styles like "resize-anchors: top right bottom left;" which
			// is a convenient way to write "top: 0px; right: 100%; bottom: 100%; 
			// left: 0;" (It is not the same as "width: 100%; height: 100%;"
			// which with margins, borders and padding could make the whole
			// container larger than the resize container or stage.)
			//
			// Note that we always set the pin-to-stage style to true. This
			// is fine because this style takes lower precedence than the
			// conflicting but manually set pin-to-container style.
			//
			if ( value.toLowerCase ( ).indexOf ( "top"    ) >= 0 ) styles.push ( { styleDefn: allStyles [ "top"    ], value: 0 } );
			if ( value.toLowerCase ( ).indexOf ( "left"   ) >= 0 ) styles.push ( { styleDefn: allStyles [ "left"   ], value: 0 } );
			if ( value.toLowerCase ( ).indexOf ( "bottom" ) >= 0 ) styles.push ( { styleDefn: allStyles [ "bottom" ], value: "100%" } );
			if ( value.toLowerCase ( ).indexOf ( "right"  ) >= 0 ) styles.push ( { styleDefn: allStyles [ "right"  ], value: "100%" } );
			
			return styles;
		}
		
		/**            
		 * @private
		 */
		internal function handleFunctionRef ( styleDefn : Object, value : *, rawValue : Boolean = false ) : Array
		{
			var result : Array = [ { styleDefn: styleDefn, value: value } ];
			if ( ! rawValue ) return result;
			
			var fnRef : Function;
			if ( value != null ) 
			{
				fnRef = document.externalAssetManager.getDefinition ( value );
				if ( fnRef == null ) 
				Debugger.logMessage ( Debugger.WARNING, "StylesManager", "unable to load function \"" + value + "\" for style " + styleDefn.style );
			}
			result [ 0 ].value = fnRef;
			return result;
		}
		
		public static var colorValues : Object = 
			{
				aliceblue: "#F0F8FF", antiquewhite: "#FAEBD7", aqua: "#00FFFF", aquamarine: "#7FFFD4", azure: "#F0FFFF", beige: "#F5F5DC", bisque: "#FFE4C4", black: "#000000", 
				blanchedalmond: "#FFEBCD", blue: "#0000FF", blueviolet: "#8A2BE2", brown: "#A52A2A", burlywood: "#DEB887", cadetblue: "#5F9EA0", chartreuse: "#7FFF00", 
				chocolate: "#D2691E", coral: "#FF7F50", cornflowerblue: "#6495ED", cornsilk: "#FFF8DC", crimson: "#DC143C", cyan: "#00FFFF", darkblue: "#00008B", 
				darkcyan: "#008B8B", darkgoldenrod: "#B8860B", darkgray: "#A9A9A9", darkgreen: "#006400", darkkhaki: "#BDB76B", darkmagenta: "#8B008B", darkolivegreen: "#556B2F",
				darkorange: "#FF8C00", darkorchid: "#9932CC", darkred: "#8B0000", darksalmon: "#E9967A", darkseagreen: "#8FBC8F", darkslateblue: "#483D8B", 
				darkslategray: "#2F4F4F", darkturquoise: "#00CED1", darkviolet: "#9400D3", deeppink: "#FF1493", deepskyblue: "#00BFFF", dimgray: "#696969", dodgerblue: "#1E90FF", 
				firebrick: "#B22222", floralwhite: "#FFFAF0", forestgreen: "#228B22", fuchsia: "#FF00FF", gainsboro: "#DCDCDC", ghostwhite: "#F8F8FF", gold: "#FFD700", 
				goldenrod: "#DAA520", gray: "#808080", green: "#008000", greenyellow: "#ADFF2F", honeydew: "#F0FFF0", hotpink: "#FF69B4", indianred: "#CD5C5C", indigo: "#4B0082", 
				ivory: "#FFFFF0", khaki: "#F0E68C", lavender: "#E6E6FA", lavenderblush: "#FFF0F5", lawngreen: "#7CFC00", lemonchiffon: "#FFFACD", lightblue: "#ADD8E6", 
				lightcoral: "#F08080", lightcyan: "#E0FFFF", lightgoldenrodyellow: "#FAFAD2", lightgrey: "#D3D3D3", lightgreen: "#90EE90", lightpink: "#FFB6C1", 
				lightsalmon: "#FFA07A", lightseagreen: "#20B2AA", lightskyblue: "#87CEFA", lightslategray: "#778899", lightsteelblue: "#B0C4DE", lightyellow: "#FFFFE0", 
				lime: "#00FF00", limegreen: "#32CD32", linen: "#FAF0E6", magenta: "#FF00FF", maroon: "#800000", mediumaquamarine: "#66CDAA", mediumblue: "#0000CD", 
				mediumorchid: "#BA55D3", mediumpurple: "#9370D8", mediumseagreen: "#3CB371", mediumslateblue: "#7B68EE", mediumspringgreen: "#00FA9A", mediumturquoise: "#48D1CC", 
				mediumvioletred: "#C71585", midnightblue: "#191970", mintcream: "#F5FFFA", mistyrose: "#FFE4E1", moccasin: "#FFE4B5", navajowhite: "#FFDEAD", navy: "#000080", 
				oldlace: "#FDF5E6", olive: "#808000", olivedrab: "#6B8E23", orange: "#FFA500", orangered: "#FF4500", orchid: "#DA70D6", palegoldenrod: "#EEE8AA", 
				palegreen: "#98FB98", paleturquoise: "#AFEEEE", palevioletred: "#D87093", papayawhip: "#FFEFD5", peachpuff: "#FFDAB9", peru: "#CD853F", pink: "#FFC0CB", 
				plum: "#DDA0DD", powderblue: "#B0E0E6", purple: "#800080", red: "#FF0000", rosybrown: "#BC8F8F", royalblue: "#4169E1", saddlebrown: "#8B4513", salmon: "#FA8072", 
				sandybrown: "#F4A460", seagreen: "#2E8B57", seashell: "#FFF5EE", sienna: "#A0522D", silver: "#C0C0C0", skyblue: "#87CEEB", slateblue: "#6A5ACD", 
				slategray: "#708090", snow: "#FFFAFA", springgreen: "#00FF7F", steelblue: "#4682B4", tan: "#D2B48C", teal: "#008080", thistle: "#D8BFD8", tomato: "#FF6347", 
				turquoise: "#40E0D0", violet: "#EE82EE", wheat: "#F5DEB3", white: "#FFFFFF", whitesmoke: "#F5F5F5", yellow: "#FFFF00", yellowgreen: "#9ACD32"
			}
		
		/**            
		 * @private
		 */
		internal function handleColorName ( styleDefn : Object, value : *, rawValue : Boolean = false ) : Array
		{
			var hexValue : * = value;
			
			if ( value is String && colorValues [ value.toLowerCase ( ) ] != null ) hexValue = colorValues [ value.toLowerCase ( ) ];
			
			return [ { styleDefn: styleDefn, value: value != null ? Styles.convertValue ( styleDefn, hexValue ) : value } ];
		}
		
		/**            
		 * @private
		 */
		internal function handleFourValues ( styleDefn : Object, value : *, rawValue : Boolean = false ) : Array
		{
			var styles : Array;
			
			switch ( styleDefn.style )
			{
				case "margin":
					styles = [ 
						{ styleDefn: allStyles [ "margin-top"    ] }, 
						{ styleDefn: allStyles [ "margin-right"  ] }, 
						{ styleDefn: allStyles [ "margin-bottom" ] }, 
						{ styleDefn: allStyles [ "margin-left"   ] }
					];
					break;
					
				case "padding":
					styles = [ 
						{ styleDefn: allStyles [ "padding-top"    ] }, 
						{ styleDefn: allStyles [ "padding-right"  ] }, 
						{ styleDefn: allStyles [ "padding-bottom" ] }, 
						{ styleDefn: allStyles [ "padding-left"   ] }
					];
					break;
					
				case "border-width":
					styles = [ 
						{ styleDefn: allStyles [ "border-top-width"    ] }, 
						{ styleDefn: allStyles [ "border-right-width"  ] }, 
						{ styleDefn: allStyles [ "border-bottom-width" ] }, 
						{ styleDefn: allStyles [ "border-left-width"   ] }
					];
					break;
			}
			
			var values : Array = [ ];
			var result : Object;
			var lastIndex : uint = 0;
			var lengthSpec : RegExp = /((-?\d+(\.\d+)?|\.\d+)(px|%)?|auto)(\s+leftover)?(\s|$)/g;
			while ( ( result = lengthSpec.exec ( value ) ) != null )
			{
				values.push ( Util.trim ( result [ 0 ] ) );
			}
			
			switch ( values.length ) 
			{
				case 1:
					styles [ 0 ].value = styles [ 1 ].value = styles [ 2 ].value = styles [ 3 ].value = values [ 0 ];
					break;
					
				case 2:
					styles [ 0 ].value = styles [ 2 ].value = values [ 0 ]; 
					styles [ 1 ].value = styles [ 3 ].value = values [ 1 ];
					break;
					
				case 3:
					styles [ 0 ].value = values [ 0 ]; 
					styles [ 1 ].value = styles [ 3 ].value = values [ 1 ];
					styles [ 2 ].value = values [ 2 ];
					break;
					
				case 4:
					styles [ 0 ].value = values [ 0 ]; 
					styles [ 1 ].value = values [ 1 ];
					styles [ 2 ].value = values [ 2 ];
					styles [ 3 ].value = values [ 3 ];
					break;
			}
			
			for each ( var style : Object in styles ) style.value = Styles.convertValue ( style.styleDefn, style.value );
			
			return styles;
		}
		
		public function registerStylesheetSelector ( stylesheetSelector : StylesheetSelector ) : StylesheetSelector
		{
			stylesheetSelectors [ stylesheetSelector ] = stylesheetSelector;
			
			if ( stylesheetSelector.rulesetId != null ) 
			{
				if ( stylesheetSelectorsIdMap [ stylesheetSelector.rulesetId ] == null ) stylesheetSelectorsIdMap [ stylesheetSelector.rulesetId ] = [ ]; 
				stylesheetSelectorsIdMap [ stylesheetSelector.rulesetId ].push ( stylesheetSelector );
			}
			
			if ( stylesheetSelectorsNameMap [ stylesheetSelector.name ] == null ) stylesheetSelectorsNameMap [ stylesheetSelector.name ] = [ ];
			stylesheetSelectorsNameMap [ stylesheetSelector.name ].push ( stylesheetSelector );
			
			return stylesheetSelector;
		}
		
		public function unregisterStylesheetSelector ( stylesheetSelector : StylesheetSelector ) : void
		{
			if ( stylesheetSelector.rulesetId != null && stylesheetSelectorsIdMap [ stylesheetSelector.rulesetId ] != null )
			{
				var index : int = stylesheetSelectorsIdMap [ stylesheetSelector.rulesetId ].indexOf ( stylesheetSelector );
				if ( index >= 0 ) stylesheetSelectorsIdMap [ stylesheetSelector.rulesetId ].splice ( index, 1 );
			}
			
			if ( stylesheetSelectorsNameMap [ stylesheetSelector.name ] != null )
			{
				index = stylesheetSelectorsNameMap [ stylesheetSelector.name ].indexOf ( stylesheetSelector );
				if ( index >= 0 ) stylesheetSelectorsNameMap [ stylesheetSelector.name ].splice ( index, 1 );
			}
		
			delete stylesheetSelectors [ stylesheetSelector ];
		}
		
		public function getStylesheetSelectors ( index : String ) : Array
		{
			if ( stylesheetSelectorsIdMap [ index ] != null && stylesheetSelectorsIdMap [ index ].length > 0 ) return stylesheetSelectorsIdMap [ index ];
			if ( stylesheetSelectorsNameMap [ index ] != null && stylesheetSelectorsNameMap [ index ].length > 0 ) return stylesheetSelectorsNameMap [ index ];
			return null;
		}
    }
}

